package org.neogenesis.web.dao;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.neogenesis.web.model.Gene;
import org.neogenesis.web.model.GeneAlia;
import org.neogenesis.web.qualifier.DataRepository;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

@SessionScoped
public class GeneDAO implements Serializable {

	@Inject
	@DataRepository
	private EntityManager em;

	@Inject
	private GeneAliasDAO geneAliasDAO;

	

	public GeneDAO() {
		
	}

	public Gene findBySymbol(String symbol) {
		Query q = em.createQuery(
				"SELECT g FROM Gene g WHERE g.geneSymbol = :geneSymbol",
				Gene.class);

		q.setParameter("geneSymbol", symbol);

		List<Gene> genes = q.getResultList();

		if (genes.size() > 0)
			return genes.get(0);

		return null;
	}

	public void create(Gene gene) {
		em.persist(gene);
	}

	public void edit(Gene gene) {
		em.merge(gene);
	}

	public void remove(Gene gene) {
		em.remove(em.merge(gene));
	}

	public Gene find(Object id) {
		return em.find(Gene.class, id);
	}

	public Gene findBySymbolAndAlias(String symbol) {
		Gene gene = findBySymbol(symbol);
		if (gene != null)
			return gene;

		GeneAlia geneAlia = geneAliasDAO.findByGeneSymbol(symbol);

		if (geneAlia == null)
			return null;

		return geneAlia.getGene();
	}

	public List<Gene> findAll() {
		CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
		cq.select(cq.from(Gene.class));
		return em.createQuery(cq).getResultList();
	}

	public List<Gene> findRange(int[] range) {
		CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
		cq.select(cq.from(Gene.class));
		javax.persistence.Query q = em.createQuery(cq);
		q.setMaxResults(range[1] - range[0]);
		q.setFirstResult(range[0]);
		return q.getResultList();
	}

	public int count() {
		javax.persistence.criteria.CriteriaQuery cq = em.getCriteriaBuilder()
				.createQuery();
		javax.persistence.criteria.Root<Gene> rt = cq.from(Gene.class);
		cq.select(em.getCriteriaBuilder().count(rt));
		javax.persistence.Query q = em.createQuery(cq);
		return ((Long) q.getSingleResult()).intValue();
	}

}
